package com.fcscs.cservice.dao.hibernate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.fcscs.core.dao.ConnectionManager;
import com.fcscs.core.domain.BaseEntity;
import com.fcscs.core.domain.BaseEntity.DBLoc;
import com.fcscs.core.service.PropertyManager;
import com.fcscs.cservice.common.CServiceCommonEnums.EditableCategoryEnum;
import com.fcscs.cservice.common.CServiceCommonEnums.NotifType;
import com.fcscs.cservice.common.CServiceCommonEnums.ReservationStatus;
import com.fcscs.cservice.common.CServiceCommonEnums.TemplateType;
import com.fcscs.cservice.common.CServiceConstants;
import com.fcscs.cservice.dao.CServiceCommonDao;
import com.fcscs.cservice.domain.AuthenticationConfig;
import com.fcscs.cservice.domain.ConstantsLanguageValue;
import com.fcscs.cservice.domain.Country;
import com.fcscs.cservice.domain.ExpressCheckInConfig;
import com.fcscs.cservice.domain.FieldEditability;
import com.fcscs.cservice.domain.HouseKeepingConfig;
import com.fcscs.cservice.domain.IGuestUserProfileView;
import com.fcscs.cservice.domain.IGuestUserView;
import com.fcscs.cservice.domain.InterfaceConfig;
import com.fcscs.cservice.domain.InterfaceConfiguration;
import com.fcscs.cservice.domain.Language;
import com.fcscs.cservice.domain.Nationality;
import com.fcscs.cservice.domain.NotifDestination;
import com.fcscs.cservice.domain.NotifTemplate;
import com.fcscs.cservice.domain.PaymentMethod;
import com.fcscs.cservice.domain.PropertyConfiguration;
//import com.fcscs.cservice.domain.ReservationStatus;
import com.fcscs.cservice.domain.RoomStatus;
import com.fcscs.cservice.domain.State;
import com.fcscs.cservice.domain.Title;
import com.fcscs.cservice.domain.model.CheckInConfiguration;
import com.fcscs.cservice.domain.model.CheckOutConfiguration;
import com.fcscs.cservice.domain.model.CountryView;
import com.fcscs.cservice.domain.model.ReservationConf;
import com.fcscs.cservice.domain.model.ReservationConfView;
import com.fcscs.cservice.domain.model.ReservationConf;
import com.fcscs.cservice.domain.model.StateView;
import com.fcscs.ecms.domain.GlobalLanguage;

@Repository("cServiceDao")
public class CServiceCommonDaoHibernate implements CServiceCommonDao {

	@Autowired
	private ConnectionManager connMgr;
	@Autowired
	private PropertyManager propMgr;

	private static DBLoc CONFDBLoc = new PropertyConfiguration().getDBLoc();

	private static final String GET = " from ";
	private static final String GET_WHERE = " e where e.propertyId = :propId ";
	private static final String DEL = " set active = false where id = :id ";
	private static final String UPD = " update ";
	private static final String ACTIVE = " and active = true ";

	private static final String GET_COUNTRIES_V = " select id, country from country c where c.property_id = :propId " + ACTIVE;
	private static final String GET_STATES_V = " from StateView sv where sv.countryId = :countryId " + ACTIVE;
	private static final String GET_PROP_CONF = " from PropertyConfiguration pc where pc.orgId = :orgId and pc.propertyId = :propId " + ACTIVE;
	private static final String GET_LANGS_V = " select id, language from language l where l.property_id = :propId " + ACTIVE;
	private static final String GET_TITLES_V = " select id, title from title t where t.property_id = :propId " + ACTIVE;
	private static final String GET_NATNS_V = " select id, nationality from nationality n where n.property_id = :propId " + ACTIVE;
	private static final String GET_PAYMS_V = " select id, method from payment_method p where p.property_id = :propId " + ACTIVE;
//	private static final String GET_RSV_STAT_V = " select id, status from reservation_status rs where rs.property_id = :propId " + ACTIVE;
	private static final String GET_ROOM_STAT_V = " select id, room_status, color_code from room_status rs where rs.property_id = :propId " + ACTIVE;
	private static final String GET_GSA = " select gsa from property_configuration where property_id = :propId " + ACTIVE;
	private static final String GET_RSV_DAYS = " select reservation_search_days from property_configuration where property_id = :propId " + ACTIVE;
	private static final String GET_BOOK_DAYS = " select booking_search_days from property_configuration where property_id = :propId " + ACTIVE;

	private static final String GET_STATES = " from State s where s.countryId = :countryId " + ACTIVE;

	private static final String PROP_CONF_CNT = " select count(*) from property_configuration where org_id = :orgId and property_id = :propId and id <> :id " + ACTIVE;
	private static final String COUNTRY_CNT = " select count(*) from country where property_id = :propId and country = :country and id <> :id " + ACTIVE;
	private static final String STATE_CNT = " select count(*) from state where property_id = :propId and country_id = :cntyId and state = :state and id <> :id " + ACTIVE;
	private static final String LANG_CNT = " select count(*) from language where property_id = :propId and language = :language and id <> :id " + ACTIVE;
	private static final String TITLE_CNT = " select count(*) from title where property_id = :propId and title = :title and id <> :id " + ACTIVE;
	private static final String NATN_CNT = " select count(*) from nationality where property_id = :propId and nationality = :nationality and id <> :id " + ACTIVE;
	private static final String PAYM_CNT = " select count(*) from payment_method where property_id = :propId and method = :method and id <> :id " + ACTIVE;
	private static final String RSV_STAT_CNT = " select count(*) from reservation_status where property_id = :propId and status = :status and id <> :id " + ACTIVE;
	private static final String ROOM_STAT_CNT = " select count(*) from room_status where property_id = :propId and room_status = :status and id <> :id " + ACTIVE;
	
	private static final String FIELD_EDIT = " from FieldEditability where orgId = :orgId and propertyId = :propId ";
	private static final String FIELD_EDIT_CATEGORY = " and category in (:cats) ";
	private static final String GET_FIELD_EDIT = " from FieldEditability where id in (:ids) ";

	private static final String GET_NOTIF_DEST = " from NotifDestination where orgId = :orgId and propertyId = :propId ";
	private static final String NOTIF_DEST_TYPES = " and notifType in (:types) ";
	private static final String NOTIF_DEST_TYPE = " and notifType = :type ";
	private static final String GET_NOTIF_DEST_IDS = " from NotifDestination where id in (:ids) ";

	private static final String GET_NOTIF_TMPL = " from NotifTemplate where orgId = :orgId and propertyId = :propId ";
	private static final String NOTIF_TMPL_TYPES = " and tmplType in (:types) ";
	private static final String NOTIF_TMPL_TYPE = " and tmplType = :type ";
	private static final String GET_NOTIF_TMPL_IDS = " from NotifTemplate where id in (:ids) ";

	private static final String GET_CI_CONF = " from CheckInConfiguration pc where pc.orgId = :orgId and pc.propertyId = :propId " + ACTIVE;
	private static final String GET_CO_CONF = " from CheckOutConfiguration pc where pc.orgId = :orgId and pc.propertyId = :propId " + ACTIVE;
	private static final String GET_RSV_CONF = " from ReservationConf rc where rc.orgId = :orgId and rc.propertyId = :propId " + ACTIVE;
	
	private static final String GET_INTERFACE_CONF = " from InterfaceConfiguration ic where ic.orgId = :orgId and ic.propertyId = :propId " + ACTIVE;

	private static final String AUTHEN_CNT = " select count(*) from authentication_config where property_id = :propId and login_option = :option and id <> :id " + ACTIVE;
	@SuppressWarnings("unchecked")
	@Override
	public List<CountryView> getCountryViewList(long propId) {
		SQLQuery q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_COUNTRIES_V);
		q.setLong("propId", propId);
		q.addEntity(CountryView.class);
		return q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<StateView> getStateViewList(long countryId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_STATES_V);
		q.setLong("countryId", countryId);
		return q.list();
	}

	@Override
	public PropertyConfiguration getPropertyConf(long id) {
		return (PropertyConfiguration)connMgr.getCurrentSession(CONFDBLoc).get(PropertyConfiguration.class, id);
	}

	@Override
	public PropertyConfiguration getPropertyConf(long orgId, long propId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_PROP_CONF);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		return (PropertyConfiguration) q.uniqueResult();
	}

	@Override
	public PropertyConfiguration savePropertyConf(PropertyConfiguration conf) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(conf);
		return conf;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ReservationConfView getRsvConfView(long orgId, long propId) {
		ReservationConfView conf = new ReservationConfView();
		SQLQuery q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_LANGS_V);
		q.setLong("propId", propId);
		q.addEntity(ReservationConfView.Language.class);
		conf.setLanguageList(q.list());
		q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_TITLES_V);
		q.setLong("propId", propId);
		q.addEntity(ReservationConfView.Title.class);
		conf.setTitleList(q.list());
		q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_NATNS_V);
		q.setLong("propId", propId);
		q.addEntity(ReservationConfView.Nationality.class);
		conf.setNationalityList(q.list());
		q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_PAYMS_V);
		q.setLong("propId", propId);
		q.addEntity(ReservationConfView.PaymentMethod.class);
		conf.setPaymentMethodList(q.list());
		List<ReservationStatus> tmpRsvStatusList = ReservationStatus.getStatusList();
		List<ReservationConfView.ReservationStatus> rsvStatusList = new ArrayList<ReservationConfView.ReservationStatus>(tmpRsvStatusList.size());
		for (ReservationStatus s : tmpRsvStatusList) {
			ReservationConfView.ReservationStatus status = new ReservationConfView.ReservationStatus();
			status.setReservStatusId(s.getId());
			status.setReservStatus(s.getStatusStr());
			rsvStatusList.add(status);
		}
		conf.setReservationStatusList(rsvStatusList);
		q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_ROOM_STAT_V);
		q.setLong("propId", propId);
		q.addEntity(ReservationConfView.RoomStatus.class);
		conf.setRoomStatusList(q.list());
		String currency = propMgr.getProperty(propId).getCurrency();
		if (currency == null) {
			conf.setCurrency(CServiceConstants.DEFAULT_CURRENCY);
		} else {
			conf.setCurrency(currency);
		}
		PropertyConfiguration propConf = getPropertyConf(orgId, propId);
		conf.setTandc(propConf.getTandc());
		conf.setSpg(propConf.getSpg());
		conf.setSpgSecLang(propConf.getSpgSecLang());
		conf.setSpgThdLang(propConf.getSpgSecLang());
		conf.setGsa(propConf.getGsa());
		conf.setGsaSecLang(propConf.getGsaSecLang());
		conf.setGsaThdLang(propConf.getGsaThdLang());
		conf.setCoTandc(propConf.getCoTandc());
		conf.setCoSucMsg(propConf.getCoSucMsg());
		return conf;
	}

	@Override
	public String getCurrency(long propId) {
		String currency = propMgr.getProperty(propId).getCurrency();
		if (currency == null) {
			currency = CServiceConstants.DEFAULT_CURRENCY;
		}
		return currency;
	}

	@Override
	public String getGSA(long propId) {
		SQLQuery q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_GSA);
		q.setLong("propId", propId);
		return (String) q.uniqueResult();
	}

	@Override
	public int getRsvSearchDays(long propId) {
		SQLQuery q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_RSV_DAYS);
		q.setLong("propId", propId);
		return ((Number) q.uniqueResult()).intValue();
	}

	@Override
	public int getBookSearchDays(long propId) {
		SQLQuery q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(GET_BOOK_DAYS);
		q.setLong("propId", propId);
		return ((Number) q.uniqueResult()).intValue();
	}

	@Override
	public List<Country> getCountryList(long propId) {
		return getList(propId, Country.class);
	}

	@Override
	public Country getCountry(long id) {
		return get(id, Country.class);
	}

	@Override
	public Country saveCountry(Country country) {
		return save(country);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<State> getStateList(long countryId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_STATES);
		q.setLong("countryId", countryId);
		return q.list();
	}

	@Override
	public State getState(long id) {
		return get(id, State.class);
	}

	@Override
	public State saveState(State state) {
		return save(state);
	}

	@Override
	public List<Title> getTitleList(long propId) {
		return getList(propId, Title.class);
	}

	@Override
	public Title getTitle(long id) {
		return get(id, Title.class);
	}

	@Override
	public Title saveTitle(Title title) {
		return save(title);
	}

	@Override
	public List<Language> getLanguageList(long propId) {
		return getList(propId, Language.class);
	}

	@Override
	public Language getLanguage(long id) {
		return get(id, Language.class);
	}

	@Override
	public Language saveLanguage(Language language) {
		return save(language);
	}

	@Override
	public List<PaymentMethod> getPayMethodList(long propId) {
		return getList(propId, PaymentMethod.class);
	}

	@Override
	public PaymentMethod getPayMethod(long id) {
		return get(id, PaymentMethod.class);
	}

	@Override
	public PaymentMethod savePayMethod(PaymentMethod payMethod) {
		return save(payMethod);
	}

	@Override
	public List<Nationality> getNationalityList(long propId) {
		return getList(propId, Nationality.class);
	}

	@Override
	public Nationality getNationality(long id) {
		return get(id, Nationality.class);
	}

	@Override
	public Nationality saveNationality(Nationality nationality) {
		return save(nationality);
	}

	@Override
	public List<RoomStatus> getRoomStatusList(long propId) {
		return getList(propId, RoomStatus.class);
	}

	@Override
	public RoomStatus getRoomStatus(long id) {
		return get(id, RoomStatus.class);
	}

	@Override
	public RoomStatus saveRoomStatus(RoomStatus roomStatus) {
		return save(roomStatus);
	}

/*	@Override
	public List<ReservationStatus> getRsvStatusList(long propId) {
		return getList(propId, ReservationStatus.class);
	}

	@Override
	public ReservationStatus getReservationStatus(long id) {
		return get(id, ReservationStatus.class);
	}

	@Override
	public ReservationStatus saveReservationStatus(ReservationStatus reservationStatus) {
		return save(reservationStatus);
	}*/

	@Override
	public boolean isPropertyConfTaken(long orgId, long propId, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(PROP_CONF_CNT);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isCountryTaken(long propId, String country, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(COUNTRY_CNT);
		q.setLong("propId", propId);
		q.setString("country", country);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isStateTaken(long propId, long countryId, String state, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(STATE_CNT);
		q.setLong("propId", propId);
		q.setLong("cntyId", countryId);
		q.setString("state", state);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isTitleTaken(long propId, String title, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(TITLE_CNT);
		q.setLong("propId", propId);
		q.setString("title", title);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isLanguageTaken(long propId, String language, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(LANG_CNT);
		q.setLong("propId", propId);
		q.setString("language", language);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isNationalityTaken(long propId, String nationality, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(NATN_CNT);
		q.setLong("propId", propId);
		q.setString("nationality", nationality);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isPayMethodTaken(long propId, String method, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(PAYM_CNT);
		q.setLong("propId", propId);
		q.setString("method", method);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isRsvStatusTaken(long propId, String status, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(RSV_STAT_CNT);
		q.setLong("propId", propId);
		q.setString("status", status);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public boolean isRoomStatusTaken(long propId, String status, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(ROOM_STAT_CNT);
		q.setLong("propId", propId);
		q.setString("status", status);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<FieldEditability> getFieldEditability(long orgId, long propId, List<EditableCategoryEnum> categories) {
		if (categories != null && categories.size() <= 0) {
			return null;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(FIELD_EDIT + (categories == null ? "" : FIELD_EDIT_CATEGORY));
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		if (categories != null) {
			List<String> catStrList = new ArrayList<String>(categories.size());
			for (EditableCategoryEnum cat : categories) {
				catStrList.add(cat.toString());
			}
			q.setParameterList("cats", catStrList);
		}
		return (List<FieldEditability>)q.list();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<Long, FieldEditability> getFieldEditability(Set<Long> ids) {
		Map<Long, FieldEditability> map = new HashMap<Long, FieldEditability>();
		if (ids == null || ids.size() <= 0) {
			return map;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_FIELD_EDIT);
		q.setParameterList("ids", ids);
		List<FieldEditability> list = (List<FieldEditability>)q.list();
		for (FieldEditability fe : list) {
			map.put(fe.getId(), fe);
		}
		return map;
	}

	@Override
	public List<FieldEditability> updateFieldEditability(List<FieldEditability> fieldEditList) {
		for (FieldEditability fe : fieldEditList) {
			connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(fe);
		}

		return fieldEditList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<NotifDestination> getNotifDestinations(long orgId, long propId, NotifType type) {
		if (type == null) {
			return null;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_DEST + (type == null ? "" : NOTIF_DEST_TYPE));
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		q.setString("type", type.toString());
		return (List<NotifDestination>)q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<NotifDestination> getNotifDestinations(long orgId, long propId, NotifType[] types) {
		if (types != null && types.length <= 0) {
			return null;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_DEST + (types == null || types.length <= 0 ? "" : NOTIF_DEST_TYPES));
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		if (types != null) {
			List<String> typeStrList = new ArrayList<String>(types.length);
			for (NotifType type : types) {
				typeStrList.add(type.toString());
			}
			q.setParameterList("types", typeStrList);
		}
		return (List<NotifDestination>)q.list();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<Long, NotifDestination> getNotifDestinations(Set<Long> ids) {
		Map<Long, NotifDestination> map = new HashMap<Long, NotifDestination>();
		if (ids == null || ids.size() <= 0) {
			return map;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_DEST_IDS);
		q.setParameterList("ids", ids);
		List<NotifDestination> list = (List<NotifDestination>)q.list();
		for (NotifDestination nd : list) {
			map.put(nd.getId(), nd);
		}
		return map;
	}

	@Override
	public List<NotifDestination> updateNotifDestination(List<NotifDestination> notifDestList) {
		for (NotifDestination nd : notifDestList) {
			connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(nd);
		}

		return notifDestList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<NotifTemplate> getNotifTemplates(long orgId, long propId, TemplateType type) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_TMPL + (type == null ? "" : NOTIF_TMPL_TYPE));
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		q.setString("type", type.toString());
		return (List<NotifTemplate>)q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<NotifTemplate> getNotifTemplates(long orgId, long propId, TemplateType[] types) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_TMPL + (types == null || types.length <= 0 ? "" : NOTIF_TMPL_TYPES));
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		if (types != null) {
			List<String> typeStrList = new ArrayList<String>(types.length);
			for (TemplateType type : types) {
				typeStrList.add(type.toString());
			}
			q.setParameterList("types", typeStrList);
		}
		return (List<NotifTemplate>)q.list();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<Long, NotifTemplate> getNotifTemplates(Set<Long> ids) {
		Map<Long, NotifTemplate> map = new HashMap<Long, NotifTemplate>();
		if (ids == null || ids.size() <= 0) {
			return map;
		}
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_NOTIF_TMPL_IDS);
		q.setParameterList("ids", ids);
		List<NotifTemplate> list = (List<NotifTemplate>)q.list();
		for (NotifTemplate nt : list) {
			map.put(nt.getId(), nt);
		}
		return map;
	}

	@Override
	public List<NotifTemplate> updateNotifTemplate(List<NotifTemplate> notifTmplList) {
		for (NotifTemplate nd : notifTmplList) {
			connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(nd);
		}

		return notifTmplList;
	}

	@SuppressWarnings("unchecked")
	private <E extends BaseEntity> E get(long id, Class<E> cls) {
		return (E) connMgr.getCurrentSession(CONFDBLoc).load(cls, id);
	}

	@SuppressWarnings("unchecked")
	private <E extends BaseEntity> List<E> getList(long propId, Class<E> cls) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET + cls.getSimpleName() + GET_WHERE + ACTIVE);
		q.setLong("propId", propId);
		return q.list();
	}
	
	private <E extends BaseEntity> E save(E entity) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(entity);
		return entity;
	}

	private <E extends BaseEntity> Boolean delete(E del) {
		return connMgr.getCurrentSession(CONFDBLoc).createQuery(UPD + del.getClass().getSimpleName() +DEL)
					.setLong("id", del.getId()).executeUpdate() == 1;
	}

	private <E extends BaseEntity> void permDelete(E s) {
		connMgr.getCurrentSession(CONFDBLoc).delete(s);		
	}

	@Override
	public boolean deleteCountry(Country country) {
		return delete(country);
	}

	@Override
	public void permDeleteCountry(Country country) {
		permDelete(country);
	}

	@Override
	public boolean deleteState(State state) {
		return delete(state);
	}

	@Override
	public void permDeleteState(State state) {
		permDelete(state);
	}

	@Override
	public boolean deleteTitle(Title title) {
		return delete(title);
	}

	@Override
	public void permDeleteTitle(Title title) {
		permDelete(title);
	}

	@Override
	public boolean deleteLanguage(Language language) {
		return delete(language);
	}

	@Override
	public void permDeleteLanguage(Language language) {
		permDelete(language);
	}

	@Override
	public boolean deleteNationality(Nationality nationality) {
		return delete(nationality);
	}

	@Override
	public void permDeleteNationality(Nationality nationality) {
		permDelete(nationality);
	}

	@Override
	public boolean deletePayMethod(PaymentMethod method) {
		return delete(method);
	}

	@Override
	public void permDeletePayMethod(PaymentMethod method) {
		permDelete(method);
	}

/*	@Override
	public boolean deleteRsvStatus(ReservationStatus status) {
		return delete(status);
	}

	@Override
	public void permDeleteRsvStatus(ReservationStatus status) {
		permDelete(status);
	}*/

	@Override
	public boolean deleteRoomStatus(RoomStatus status) {
		return delete(status);
	}

	@Override
	public void permDeleteRoomStatus(RoomStatus status) {
		permDelete(status);
	}

	@Override
	public CheckInConfiguration getCheckInConf(long id) {
		return (CheckInConfiguration)connMgr.getCurrentSession(CONFDBLoc).get(CheckInConfiguration.class, id);
	}

	@Override
	public CheckInConfiguration getCheckInConf(long orgId, long propId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_CI_CONF);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		return (CheckInConfiguration) q.uniqueResult();
	}

	@Override
	public CheckInConfiguration saveCheckInConf(CheckInConfiguration conf) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(conf);
		return conf;
	}

	@Override
	public CheckOutConfiguration getCheckOutConf(long id) {
		return (CheckOutConfiguration)connMgr.getCurrentSession(CONFDBLoc).get(CheckOutConfiguration.class, id);
	}

	@Override
	public CheckOutConfiguration getCheckOutConf(long orgId, long propId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_CO_CONF);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		return (CheckOutConfiguration) q.uniqueResult();
	}

	@Override
	public CheckOutConfiguration saveCheckOutConf(CheckOutConfiguration conf) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(conf);
		return conf;
	}

	@Override
	public ReservationConf getRsvConf(long id) {
		return (ReservationConf)connMgr.getCurrentSession(CONFDBLoc).get(ReservationConf.class, id);
	}

	@Override
	public ReservationConf getRsvConf(long orgId, long propId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_RSV_CONF);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		return (ReservationConf) q.uniqueResult();
	}

	@Override
	public InterfaceConfiguration saveInterfaceConf(InterfaceConfiguration conf) {
		return this.save(conf);
	}

	@Override
	public InterfaceConfiguration getInterfaceConf(long orgId, long propId) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(GET_INTERFACE_CONF);
		q.setLong("orgId", orgId);
		q.setLong("propId", propId);
		return (InterfaceConfiguration) q.uniqueResult();
	}

	@Override
	public InterfaceConfiguration getInterfaceConf(long id) {
		return this.get(id, InterfaceConfiguration.class);
	}


	@SuppressWarnings("unchecked")
	@Override
	public List<IGuestUserView> getListIGuestUserView() {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from IGuestUserView");
		return q.list();
	}
	
	@Override
	public Map<String, String> getLanguageMap() {
		Query query = connMgr.getCurrentSession(CONFDBLoc).createQuery("from GlobalLanguage");
		@SuppressWarnings("unchecked")
		List<GlobalLanguage> langs = (List<GlobalLanguage>)query.list();
		Map<String, String> rs = new HashMap<String, String>();
		for(GlobalLanguage lang : langs){
			rs.put(lang.getId(), lang.getDescription());
		}
		return rs;
	}

	@Override
	public IGuestUserProfileView getIGuestUserProfileView() {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from IGuestUserProfileView");
		return (IGuestUserProfileView)q.list();
	}
	
	//iGuest Authentication
	@Override
	public AuthenticationConfig getAuthen(long propId,long orgId ){

		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from AuthenticationConfig where propertyId=:propId and orgId=:orgId");
		q.setLong("propId", propId);
		q.setLong("orgId",orgId);
		return (AuthenticationConfig)q.uniqueResult();
		}

	@Override
	public AuthenticationConfig SaveAuthen(AuthenticationConfig authen) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(authen);
		return authen;
	}
	@Override
	public boolean isAuthenTaken(long propId, int option, Long id) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createSQLQuery(AUTHEN_CNT);
		q.setLong("propId", propId);
		q.setLong("loginOption", option);
		q.setLong("id", id == null ? -1 : id);
		return ((Number) q.uniqueResult()).intValue() > 0;
	}

	@Override
	public ExpressCheckInConfig saveExpressCheckInConfig(
			ExpressCheckInConfig expressCheckIn) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(expressCheckIn);
		return expressCheckIn;
	}

	@Override
	public ExpressCheckInConfig getExpressCheckInConfig(long id) {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from ExpressCheckInConfig");
		
		@SuppressWarnings("unchecked")
		List<ExpressCheckInConfig> list = (List<ExpressCheckInConfig>) q.list();
		
		return list.get(0);
	}

	@Override
	public ConstantsLanguageValue saveConstantsLanguageValue(
			ConstantsLanguageValue constants) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(constants);
		return constants;
	}
	@Override
	public List<ConstantsLanguageValue> getListConstantsLanguage(long propId,long orgId,String constant) {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from ConstantsLanguageValue where id.propertyId=:propId and id.orgId=:orgId and id.constants=:constant");
		q.setLong("propId", propId);
		q.setLong("orgId", orgId);
		q.setString("constant", constant);
		return q.list();

		}

	@Override
	public HouseKeepingConfig saveHousepeepingConfig(
			HouseKeepingConfig currentHousekeepingConf) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(currentHousekeepingConf);
		return currentHousekeepingConf;
	}

	@Override
	public HouseKeepingConfig getHousekeepingConfig(long propertyId) {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from HouseKeepingConfig");
		
		@SuppressWarnings("unchecked")
		List<HouseKeepingConfig> list = (List<HouseKeepingConfig>) q.list();
		
		return list.get(0);
	}

	@Override
	public InterfaceConfig getInterfaceConfig(Long propertyId) {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery("from InterfaceConfig");
		
		@SuppressWarnings("unchecked")
		List<InterfaceConfig> list = (List<InterfaceConfig>) q.list();
		
//		return list.get(0);
		return (InterfaceConfig) q.uniqueResult();
	}

	@Override
	public InterfaceConfig saveInterfaceConfig(InterfaceConfig currentInterConf) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(currentInterConf);
		return currentInterConf;
	}

	
}
